/*********************************************************************************
 *      Copyright:  (C) 2025 ZYT
 *                  All rights reserved.
 *
 *       Filename:  can_comm.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(10/08/25)
 *         Author:  ZYT <zhangyuting@163.com>
 *      ChangeLog:  1, Release initial version on "10/08/25 09:17:16"
 *                 
 ********************************************************************************/
#include "can_comm.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <fcntl.h>
#include <errno.h>

static int can_socket_fd = -1;

//can初始化函数
int can_comm_init(void) 
{
	struct sockaddr_can 	addr;
	struct ifreq 			ifr;

	can_socket_fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
	if (can_socket_fd < 0) 
	{
		perror("socket");
		return -1;
	}

	strcpy(ifr.ifr_name, CAN_DEVICE);
	if (ioctl(can_socket_fd, SIOCGIFINDEX, &ifr) < 0) 
	{
		perror("ioctl");
		close(can_socket_fd);
		can_socket_fd = -1;
		return -1;
	}

	addr.can_family = AF_CAN;
	addr.can_ifindex = ifr.ifr_ifindex;

	if (bind(can_socket_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) 
	{
		perror("bind");
		close(can_socket_fd);
		can_socket_fd = -1;
		return -1;
	}

	printf("[CAN] %s initialized successfully.\n", CAN_DEVICE);
	return can_socket_fd;
}

//bridge线程发送can帧到单片机
int can_comm_send(const struct can_frame *frame) 
{
	int		ret;

	if (can_socket_fd < 0 || frame == NULL) 
		return -1;
	ret = write(can_socket_fd, frame, sizeof(*frame));
	if (ret != sizeof(*frame)) 
	{
		perror("CAN send error");
		return -1;
	}
	return 0;
}

//bridge线程接收由单片机发来的can帧
int can_comm_receive(struct can_frame *frame) 
{
	int		ret;

	if (can_socket_fd < 0 || frame == NULL)//套接字出错或can帧为空 
		return -1;
	ret = read(can_socket_fd, frame, sizeof(*frame));
	if (ret == sizeof(*frame)) //成功读取到can帧
		return 0;
	if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))//read出错
		return 1;
	if (ret < 0) //read出错
		perror("CAN receive error");
	return -1;
}

void can_comm_close(void) 
{
	if (can_socket_fd >= 0) 
	{
		close(can_socket_fd);
		can_socket_fd = -1;
	}
}

int can_comm_get_socket(void) 
{
	return can_socket_fd;
}

